package partB;

import misc.not_Legal_Exception;
import evolution_superclasses.Genotype;
import evolution_superclasses.Phenotype;

public class B_Phenotype extends Phenotype {
	protected double[] _weights;
	private double _entropy;
	
	public B_Phenotype(B_Genotype gen) {
		super(gen);
	}

	public double[] get_weights() {
		return _weights;
	}

	public void set_weights(double[] weights) {
		_weights = weights;
	}
	
	public void win(){
		set_fitness(get_fitness()+2);
	}
	
	public void tie(){
		set_fitness(get_fitness()+1);
	}

	public double get_entropy() {
		return _entropy;
	}

	public void set_entropy(double entropy) {
		_entropy = entropy;
	}
	
	private void calculateEntropy(){
		double result = 0;
		for(double resource: _weights)
			result += resource*log2(resource);
		set_entropy(-1*result);
	}
	
	private double log2(double x)
	{
		if(x==0)return 0;//Actually undefined or -Inf, yet it is multiplied with 0 in the method above.
	    return (Math.log(x) / Math.log(2));
	}

	@Override
	protected void develop(Genotype gen) throws not_Legal_Exception {
		if(gen.get_genSize()%4!=0)throw new not_Legal_Exception("B genotypes must be a multiple of 4");
		_weights = new double[gen.get_genSize()/4];
		boolean[] bs = ((B_Genotype)gen).get_binaryArray();

		int count = 0;
		double value, total = 0;
		for(int i = 0; i < gen.get_genSize();){
			value = (bs[i++]?1:0)+(bs[i++]?2:0)+(bs[i++]?4:0)+(bs[i++]?8:0);
			_weights[count++] = value;
			total += value;
		}
		
		for(int i = 0; i < _weights.length; i++){
			_weights[i] /= total;
		}
		
		calculateEntropy();
	}

	@Override
	public String toString() {
		String s = "\t";
		//Increase readability
		for(double i :get_weights()){
			s += (Math.round(i*100))+"\t";
		}
		return s;
	}

	public String toActualString() {
		String s = "\t";
		//Increase readability
		for(double i :get_weights()){
			s += i+"\t";
		}
		return s;
	}

}
